package io.aicn.lowcode.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.aicn.lowcode.generator.model.ColumnInfo;
import io.aicn.lowcode.generator.model.TableInfo;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 表元数据服务类
 * 负责解析新的JSON格式表定义，支持表继承、全局字段、领域字段等特性
 */
@Service
public class TableMetadataService {
    
    private static final Logger log = LoggerFactory.getLogger(TableMetadataService.class);
    
    @Autowired
    private ObjectMapper objectMapper;

    private JsonNode metadataConfig;
    private JsonNode metadataSchema;

    /**
     * 初始化元数据配置
     */
    public void initializeMetadata() {
        try {
            // 加载元数据配置
            ClassPathResource configResource = new ClassPathResource("table-metadata-config.json");
            metadataConfig = objectMapper.readTree(configResource.getInputStream());
            
            // 加载元数据Schema
            ClassPathResource schemaResource = new ClassPathResource("base/table-metadata.schema.json");
            metadataSchema = objectMapper.readTree(schemaResource.getInputStream());
            
            log.info("表元数据配置初始化完成");
        } catch (IOException e) {
            log.error("初始化表元数据配置失败", e);
            throw new RuntimeException("初始化表元数据配置失败: " + e.getMessage());
        }
    }

    /**
     * 解析JSON格式的表定义
     * @param tableJsonPath 表定义JSON文件路径
     * @return TableInfo对象
     */
    public TableInfo parseTableDefinition(String tableJsonPath) {
        try {
            if (metadataConfig == null) {
                initializeMetadata();
            }

            ClassPathResource resource = new ClassPathResource(tableJsonPath);
            JsonNode tableDefinition = objectMapper.readTree(resource.getInputStream());
            
            return buildTableInfo(tableDefinition);
        } catch (IOException e) {
            log.error("解析表定义失败: {}", tableJsonPath, e);
            throw new RuntimeException("解析表定义失败: " + e.getMessage());
        }
    }

    /**
     * 根据表名解析表定义
     * @param tableName 表名
     * @return TableInfo对象
     */
    public TableInfo parseTableDefinitionByName(String tableName) {
        String jsonPath = tableName + "-table.json";
        return parseTableDefinition(jsonPath);
    }

    /**
     * 构建TableInfo对象
     * @param tableDefinition 表定义JSON节点
     * @return TableInfo对象
     */
    private TableInfo buildTableInfo(JsonNode tableDefinition) {
        TableInfo tableInfo = new TableInfo();
        
        // 基本信息
        tableInfo.setTableName(tableDefinition.get("tableName").asText());
        tableInfo.setTableComment(tableDefinition.get("tableComment").asText());
        
        // 构建列信息
        List<ColumnInfo> columns = new ArrayList<>();
        
        // 添加全局字段
        addGlobalFields(columns, tableDefinition.get("useGlobalFields"));
        
        // 添加领域字段
        addDomainFields(columns, tableDefinition.get("useDomainFields"));
        
        // 添加自定义字段
        addCustomFields(columns, tableDefinition.get("customFields"));
        
        tableInfo.setColumns(columns);
        
        // 设置主键
        setPrimaryKey(tableInfo, columns);
        
        return tableInfo;
    }

    /**
     * 添加全局字段
     * @param columns 列列表
     * @param useGlobalFields 使用的全局字段配置
     */
    private void addGlobalFields(List<ColumnInfo> columns, JsonNode useGlobalFields) {
        if (useGlobalFields == null) {
            return;
        }
        
        JsonNode globalFields = metadataConfig.get("globalFields");
        
        // 添加必需的全局字段
        JsonNode requiredFields = useGlobalFields.get("required");
        if (requiredFields != null && requiredFields.isArray()) {
            for (JsonNode fieldName : requiredFields) {
                String name = fieldName.asText();
                ColumnInfo column = findGlobalField(globalFields.get("required"), name);
                if (column != null) {
                    columns.add(column);
                }
            }
        }
        
        // 添加可选的全局字段
        JsonNode optionalFields = useGlobalFields.get("optional");
        if (optionalFields != null && optionalFields.isArray()) {
            for (JsonNode fieldName : optionalFields) {
                String name = fieldName.asText();
                ColumnInfo column = findGlobalField(globalFields.get("optional"), name);
                if (column != null) {
                    columns.add(column);
                }
            }
        }
    }

    /**
     * 添加领域字段
     * @param columns 列列表
     * @param useDomainFields 使用的领域字段配置
     */
    private void addDomainFields(List<ColumnInfo> columns, JsonNode useDomainFields) {
        if (useDomainFields == null) {
            return;
        }
        
        JsonNode domainFields = metadataConfig.get("domainFields");
        
        Iterator<Map.Entry<String, JsonNode>> domainIterator = useDomainFields.fields();
        while (domainIterator.hasNext()) {
            Map.Entry<String, JsonNode> domainEntry = domainIterator.next();
            String domainName = domainEntry.getKey();
            JsonNode domainConfig = domainEntry.getValue();
            
            JsonNode domainDefinition = domainFields.get(domainName);
            if (domainDefinition == null) {
                continue;
            }
            
            // 添加必需的领域字段
            JsonNode requiredFields = domainConfig.get("required");
            if (requiredFields != null && requiredFields.isArray()) {
                for (JsonNode fieldName : requiredFields) {
                    String name = fieldName.asText();
                    ColumnInfo column = findDomainField(domainDefinition.get("required"), name);
                    if (column != null) {
                        columns.add(column);
                    }
                }
            }
            
            // 添加可选的领域字段
            JsonNode optionalFields = domainConfig.get("optional");
            if (optionalFields != null && optionalFields.isArray()) {
                for (JsonNode fieldName : optionalFields) {
                    String name = fieldName.asText();
                    ColumnInfo column = findDomainField(domainDefinition.get("optional"), name);
                    if (column != null) {
                        columns.add(column);
                    }
                }
            }
        }
    }

    /**
     * 添加自定义字段
     * @param columns 列列表
     * @param customFields 自定义字段配置
     */
    private void addCustomFields(List<ColumnInfo> columns, JsonNode customFields) {
        if (customFields == null || !customFields.isArray()) {
            return;
        }
        
        for (JsonNode fieldNode : customFields) {
            ColumnInfo column = parseFieldDefinition(fieldNode);
            columns.add(column);
        }
    }

    /**
     * 查找全局字段定义
     * @param fieldsArray 字段数组
     * @param fieldName 字段名
     * @return ColumnInfo对象
     */
    private ColumnInfo findGlobalField(JsonNode fieldsArray, String fieldName) {
        if (fieldsArray == null || !fieldsArray.isArray()) {
            return null;
        }
        
        for (JsonNode fieldNode : fieldsArray) {
            if (fieldName.equals(fieldNode.get("name").asText())) {
                return parseFieldDefinition(fieldNode);
            }
        }
        return null;
    }

    /**
     * 查找领域字段定义
     * @param fieldsArray 字段数组
     * @param fieldName 字段名
     * @return ColumnInfo对象
     */
    private ColumnInfo findDomainField(JsonNode fieldsArray, String fieldName) {
        if (fieldsArray == null || !fieldsArray.isArray()) {
            return null;
        }
        
        for (JsonNode fieldNode : fieldsArray) {
            if (fieldName.equals(fieldNode.get("name").asText())) {
                return parseFieldDefinition(fieldNode);
            }
        }
        return null;
    }

    /**
     * 解析字段定义
     * @param fieldNode 字段JSON节点
     * @return ColumnInfo对象
     */
    private ColumnInfo parseFieldDefinition(JsonNode fieldNode) {
        ColumnInfo column = new ColumnInfo();
        
        column.setName(fieldNode.get("name").asText());
        column.setType(fieldNode.get("type").asText());
        column.setComment(fieldNode.has("comment") ? fieldNode.get("comment").asText() : "");
        column.setNullable(fieldNode.has("nullable") ? fieldNode.get("nullable").asBoolean() : true);
        
        // 可选属性
        if (fieldNode.has("length")) {
            column.setLength(fieldNode.get("length").asInt());
        }
        if (fieldNode.has("precision")) {
            column.setPrecision(fieldNode.get("precision").asInt());
        }
        if (fieldNode.has("scale")) {
            column.setScale(fieldNode.get("scale").asInt());
        }
        if (fieldNode.has("defaultValue")) {
            column.setDefaultValue(fieldNode.get("defaultValue").asText());
        }
        if (fieldNode.has("autoIncrement")) {
            column.setAutoIncrement(fieldNode.get("autoIncrement").asBoolean());
        }
        if (fieldNode.has("primaryKey")) {
            column.setPrimaryKey(fieldNode.get("primaryKey").asBoolean());
        }
        if (fieldNode.has("unique")) {
            column.setUnique(fieldNode.get("unique").asBoolean());
        }
        
        // 设置Java类型和属性名
        column.setJavaType(getJavaType(column.getType()));
        column.setJavaProperty(underscoreToCamel(column.getName()));
        
        return column;
    }

    /**
     * 设置主键
     * @param tableInfo 表信息
     * @param columns 列列表
     */
    private void setPrimaryKey(TableInfo tableInfo, List<ColumnInfo> columns) {
        for (ColumnInfo column : columns) {
            if (Boolean.TRUE.equals(column.getPrimaryKey())) {
                tableInfo.setPrimaryKey(column);
                break;
            }
        }
    }

    /**
     * SQL类型转Java类型
     * @param sqlType SQL类型
     * @return Java类型
     */
    private String getJavaType(String sqlType) {
        switch (sqlType.toUpperCase()) {
            case "TINYINT":
            case "SMALLINT":
            case "MEDIUMINT":
            case "INT":
                return "Integer";
            case "BIGINT":
                return "Long";
            case "FLOAT":
                return "Float";
            case "DOUBLE":
                return "Double";
            case "DECIMAL":
                return "BigDecimal";
            case "CHAR":
            case "VARCHAR":
            case "TEXT":
            case "MEDIUMTEXT":
            case "LONGTEXT":
                return "String";
            case "DATE":
                return "LocalDate";
            case "TIME":
                return "LocalTime";
            case "DATETIME":
            case "TIMESTAMP":
                return "LocalDateTime";
            case "BOOLEAN":
                return "Boolean";
            case "JSON":
                return "String";
            default:
                return "String";
        }
    }

    /**
     * 下划线转驼峰
     * @param input 输入字符串
     * @return 驼峰格式字符串
     */
    private String underscoreToCamel(String input) {
        if (input == null || input.isEmpty()) {
            return input;
        }
        
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = false;
        
        for (char c : input.toCharArray()) {
            if (c == '_') {
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(Character.toLowerCase(c));
                }
            }
        }
        
        return result.toString();
    }

    /**
     * 获取元数据配置
     * @return 元数据配置JSON节点
     */
    public JsonNode getMetadataConfig() {
        if (metadataConfig == null) {
            initializeMetadata();
        }
        return metadataConfig;
    }

    /**
     * 获取元数据Schema
     * @return 元数据Schema JSON节点
     */
    public JsonNode getMetadataSchema() {
        if (metadataSchema == null) {
            initializeMetadata();
        }
        return metadataSchema;
    }
}